#!/usr/bin/env python3
"""
AI代码审查MCP服务器
提供代码审查相关的MCP工具服务
"""

import asyncio
import logging
from typing import Any, Sequence

from mcp.server import Server, NotificationOptions
from mcp.server.models import InitializationOptions
from mcp.server.stdio import stdio_server
from mcp.types import (
    CallToolRequest,
    CallToolResult,
    ListToolsRequest,
    TextContent,
    Tool,
)
from pydantic import AnyUrl

from biz.mcp.tools.code_review import CodeReviewTool
from biz.mcp.tools.branch_review import BranchReviewTool
from biz.mcp.tools.complexity_review import ComplexityReviewTool
from biz.mcp.tools.directory_review import DirectoryReviewTool

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 创建服务器实例
server = Server("ai-codereview-mcp")

# 初始化工具实例
code_review_tool = CodeReviewTool()
branch_review_tool = BranchReviewTool()
complexity_review_tool = ComplexityReviewTool()
directory_review_tool = DirectoryReviewTool()

# 工具注册表
TOOLS = {
    "code_review_by_branch": code_review_tool,
    "branch_review": branch_review_tool,
    "complexity_review": complexity_review_tool,
    "directory_review": directory_review_tool,
}


@server.list_tools()
async def handle_list_tools() -> list[Tool]:
    """
    列出所有可用的工具
    """
    return [
        Tool(
            name="code_review_by_branch",
            description="对指定GitLab项目的分支进行代码审查",
            inputSchema={
                "type": "object",
                "properties": {
                    "gitlab_url": {
                        "type": "string",
                        "description": "GitLab项目URL"
                    },
                    "branch_name": {
                        "type": "string",
                        "description": "要审查的分支名称"
                    },
                    "access_token": {
                        "type": "string",
                        "description": "GitLab访问令牌（可选，如果环境变量中已配置）"
                    }
                },
                "required": ["gitlab_url", "branch_name"]
            }
        ),
        Tool(
            name="branch_review",
            description="审查GitLab项目的分支命名规范",
            inputSchema={
                "type": "object",
                "properties": {
                    "gitlab_url": {
                        "type": "string",
                        "description": "GitLab项目URL"
                    },
                    "access_token": {
                        "type": "string",
                        "description": "GitLab访问令牌（可选）"
                    }
                },
                "required": ["gitlab_url"]
            }
        ),
        Tool(
            name="complexity_review",
            description="分析代码复杂度",
            inputSchema={
                "type": "object",
                "properties": {
                    "directory": {
                        "type": "string",
                        "description": "要分析的项目目录路径"
                    },
                    "top_n": {
                        "type": "integer",
                        "description": "显示复杂度最高的文件数量",
                        "default": 10
                    }
                },
                "required": ["directory"]
            }
        ),
        Tool(
            name="directory_review",
            description="审查项目目录结构规范",
            inputSchema={
                "type": "object",
                "properties": {
                    "directory": {
                        "type": "string",
                        "description": "项目根目录路径"
                    },
                    "language": {
                        "type": "string",
                        "description": "开发语言",
                        "enum": ["python", "java", "php", "vue"]
                    },
                    "max_depth": {
                        "type": "integer",
                        "description": "目录遍历最大深度",
                        "default": 3
                    },
                    "only_dirs": {
                        "type": "boolean",
                        "description": "是否只显示目录",
                        "default": False
                    }
                },
                "required": ["directory", "language"]
            }
        )
    ]


@server.call_tool()
async def handle_call_tool(name: str, arguments: dict[str, Any] | None) -> list[TextContent]:
    """
    处理工具调用请求
    """
    if name not in TOOLS:
        raise ValueError(f"未知工具: {name}")
    
    try:
        tool = TOOLS[name]
        result = await tool.execute(arguments or {})
        
        # 添加日志记录返回结果类型和内容
        logger.info(f"工具 {name} 执行结果类型: {type(result)}")
        logger.info(f"工具 {name} 执行结果内容: {result}")
        
        # 确保结果是字符串类型
        if not isinstance(result, str):
            logger.error(f"工具 {name} 返回的结果不是字符串类型: {type(result)}")
            result_str = str(result)
            logger.info(f"已将结果转换为字符串: {result_str}")
        else:
            result_str = result
            
        return [
            TextContent(
                type="text",
                text=result_str
            )
        ]
    except Exception as e:
        logger.error(f"工具 {name} 执行失败: {e}")
        import traceback
        logger.error(f"错误详情: {traceback.format_exc()}")
        return [
            TextContent(
                type="text",
                text=f"执行失败: {str(e)}"
            )
        ]


async def main():
    """
    启动MCP服务器
    """
    # 使用stdio传输
    async with stdio_server() as (read_stream, write_stream):
        await server.run(
            read_stream,
            write_stream,
            InitializationOptions(
                server_name="ai-codereview-mcp",
                server_version="1.0.0",
                capabilities=server.get_capabilities(
                    notification_options=NotificationOptions(
                        tools_changed=True,
                        resources_changed=False,
                        prompts_changed=False
                    ),
                    experimental_capabilities={},
                ),
            ),
        )


if __name__ == "__main__":
    asyncio.run(main())